// 深度判断两个对象某个属性的值是否相等
export const isDeepEqual = (left: unknown, right: unknown, ignoredKeys?: string[]): boolean => {
  const equal = (a: unknown, b: unknown): boolean => {
    // 基本类型直接比较
    if (a === b) return true;

    // 检查是否都是非空对象
    if (a && b && typeof a === 'object' && typeof b === 'object') {
      // 检查构造函数是否相同
      if (a.constructor !== b.constructor) return false;

      let length: number;
      let i: any; // 这里使用any是因为i会用于多种类型的迭代

      // 处理数组
      if (Array.isArray(a) && Array.isArray(b)) {
        length = a.length;
        if (length !== b.length) return false;
        for (i = length; i-- !== 0; ) {
          if (!equal(a[i], b[i])) return false;
        }
        return true;
      }

      // 处理Map
      if (a instanceof Map && b instanceof Map) {
        if (a.size !== b.size) return false;
        for (i of a.entries()) {
          if (!b.has(i[0])) return false;
        }
        for (i of a.entries()) {
          if (!equal(i[1], b.get(i[0]))) return false;
        }
        return true;
      }

      // 处理Set
      if (a instanceof Set && b instanceof Set) {
        if (a.size !== b.size) return false;
        for (i of a.entries()) {
          if (!b.has(i[0])) return false;
        }
        return true;
      }

      // 处理正则表达式
      if (a instanceof RegExp && b instanceof RegExp) {
        return a.source === b.source && a.flags === b.flags;
      }

      // 处理有valueOf方法的对象
      if (typeof a.valueOf === 'function' && a.valueOf !== Object.prototype.valueOf) {
        return a.valueOf() === b.valueOf();
      }

      // 处理有toString方法的对象
      if (typeof a.toString === 'function' && a.toString !== Object.prototype.toString) {
        return a.toString() === b.toString();
      }

      // 处理普通对象
      const aKeys = Object.keys(a) as (keyof typeof a)[];
      length = aKeys.length;

      // 比较对象键的数量
      if (length !== Object.keys(b).length) return false;

      // 检查b是否包含a的所有键
      for (i = length; i-- !== 0; ) {
        if (!Object.prototype.hasOwnProperty.call(b, aKeys[i])) return false;
      }

      // 递归比较对象属性
      for (i = length; i-- !== 0; ) {
        const key = aKeys[i];

        // 忽略React内部属性
        if (key === '_owner' && (a as any).$$typeof) {
          continue;
        }

        // 忽略指定的键
        if (ignoredKeys && ignoredKeys.includes(key as string)) {
          continue;
        }

        // 递归比较属性值
        if (!equal((a as Record<string, unknown>)[key as string], (b as Record<string, unknown>)[key as string])) {
          return false;
        }
      }

      return true;
    }

    // 处理NaN（NaN !== NaN，所以需要特殊判断）
    return a !== a && b !== b;
  };

  return equal(left, right);
};
